package com.ssy.lingxi.marketing.serviceimpl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.json.JSONUtil;
import com.ssy.lingxi.common.constant.marketing.ActivityTypeEnum;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.model.bo.MemberAndRoleIdBO;
import com.ssy.lingxi.common.model.dto.MemberAndRoleIdDTO;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.common.utils.DateTimeUtil;
import com.ssy.lingxi.marketing.api.model.request.ActivityGoodsQuantityCheckRequest;
import com.ssy.lingxi.marketing.api.model.request.CartActivityPriceRequest;
import com.ssy.lingxi.marketing.api.model.response.CartActivityPriceFeignResponse;
import com.ssy.lingxi.marketing.api.model.response.CartGiveResponse;
import com.ssy.lingxi.marketing.api.model.response.CartSubsidiaryResponse;
import com.ssy.lingxi.marketing.api.model.response.SkuJoinActivityResponse;
import com.ssy.lingxi.marketing.model.bo.*;
import com.ssy.lingxi.marketing.model.constant.GoodsQuantityCheckTypeEnum;
import com.ssy.lingxi.marketing.model.dto.*;
import com.ssy.lingxi.marketing.model.vo.activity.request.ActivityGoodsSalesReq;
import com.ssy.lingxi.marketing.model.vo.activity.response.ActivityGoodsRestrictNumResp;
import com.ssy.lingxi.marketing.model.vo.activity.response.ActivityGoodsSalesResp;
import com.ssy.lingxi.marketing.model.vo.activity.response.CartActivityPriceResponse;
import com.ssy.lingxi.marketing.service.IActivityGoodsCacheService;
import com.ssy.lingxi.marketing.service.IActivityPriceCalculateService;
import com.ssy.lingxi.marketing.service.feign.IMemberFeignService;
import com.ssy.lingxi.marketing.service.feign.IProductFeignService;
import com.ssy.lingxi.marketing.service.feign.ISearchFeignService;
import com.ssy.lingxi.marketing.serviceimpl.component.activity.ActivityPriceCalculateComponent;
import com.ssy.lingxi.product.api.model.response.feign.CommodityPriceResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 活动商品计算服务实现类
 * @author yzc
 * @version 2.0.0
 * @date 2021/9/2
 */
@Slf4j
@Service
public class ActivityPriceCalculateServiceImpl implements IActivityPriceCalculateService {

    @Resource
    private IProductFeignService productFeignService;
    @Resource
    private IMemberFeignService memberFeignService;
    @Resource
    private ISearchFeignService searchFeignService;
    @Resource
    private ActivityPriceCalculateComponent activityPriceCalculateComponent;
    @Resource
    private IActivityGoodsCacheService activityGoodsCacheService;

    /**
     * 影响价格的活动：
     *  特价、直降、折扣
     *  满量、满额
     *  组合、多件
     *  换购[不能叠加]
     */

    private List<Long> getSkuId(List<CartActivityPriceDto> reqList){
        return reqList.stream().map(CartActivityPriceDto::getSkuId).collect(Collectors.toList());
    }

    private List<Long> getSkuIdExcludeSwap(List<CartActivityPriceDto> reqList){
        return reqList.stream().filter(o ->o.getParentSkuId()==null).map(CartActivityPriceDto::getSkuId).collect(Collectors.toList());
    }

    private List<Long> getSkuIdOfSwap(List<CartActivityPriceDto> reqList){
        return reqList.stream().filter(o ->o.getParentSkuId()!=null).map(CartActivityPriceDto::getSkuId).collect(Collectors.toList());
    }

    private List<CartActivityPriceDto> getSkuReqOfSwap(List<CartActivityPriceDto> reqList){
        return reqList.stream().filter(o ->o.getParentSkuId()!=null).collect(Collectors.toList());
    }

    /**
     * 调用商品服务-查询商品原价或策略价
     * @param reqList
     * @param memberId
     * @param roleId
     * @return 外key=skuId,内key=阶梯范围(0-0表示无阶梯价)，内val=价格
     *
     */
    private  Map<Long, CommodityPriceResponse> getGoodsPrice(List<CartActivityPriceDto> reqList, Long memberId, Long roleId){
        Long shopId = reqList.get(0).getShopId();
        Integer commodityType=reqList.get(0).getCommodityType();
        //获得sku集合(不排除置换商品，如果未达到置换条件，则原价购买)
        List<Long> skuIds = getSkuId(reqList);
        return productFeignService.getCommodityPriceAndMemberPriceBatch(shopId, commodityType, memberId, roleId,skuIds);
    }

    /**
     * 购买超限提示
     * @param num
     * @return
     */
    private BusinessException buildResponseCode(double num){
        //负数转0
        num=num<0?0:num;
        return new BusinessException(ResponseCode.MARKETING_ACTIVITY_GT_SKU_STORE,String.format(ResponseCode.MARKETING_ACTIVITY_GT_SKU_STORE.getMessage(),num));
    }

    /**
     * 验证购买数量是否超限
     * @param memberId
     * @param roleId
     * @param dto
     * @param activityGoodsRestrictNum
     * @param checkTypeEnum 校验类型
     */
    private double validBuyQuantity(Long memberId,Long roleId,CartActivityPriceDto dto,Map<String, ActivityGoodsRestrictNumResp> activityGoodsRestrictNum,GoodsQuantityCheckTypeEnum checkTypeEnum){
        List<ActivityGoodsBO> enableActivityList = dto.getEnableActivityList();
        if(CollectionUtil.isNotEmpty(enableActivityList)){
            //保存超买数量
            double maxDiffNum=0d;
            int restrictType=0;
            for(ActivityGoodsBO act :enableActivityList ) {
                //跳过非秒杀时段的超限验证
                if(ActivityTypeEnum.SEC_KILL.getCode().equals(act.getActivityType())){
                    SecKillBO secKillBO=(SecKillBO)act.getActivityDefined();
                    if(!isKillTime(secKillBO)) {
                        continue;
                    }
                }
                double tempNum;
                ActivityGoodsSalesReq salesReq = new ActivityGoodsSalesReq();
                salesReq.setBelongType(act.getBelongType());
                salesReq.setActivityId(act.getActivityId());
                salesReq.setMemberId(memberId);//采购商
                salesReq.setRoleId(roleId);
                salesReq.setSkuId(dto.getSkuId());
                //查询已售数量
                ActivityGoodsSalesResp goodsSale = activityGoodsCacheService.getGoodsSale(salesReq);
                ActivityGoodsRestrictNumResp resp = activityGoodsRestrictNum.get(act.getBelongType() + "_" + act.getActivityId() + "_" + dto.getSkuId());
                //跳过换购商品
                if(resp==null){
                    continue;
                }
                Double memberBuyNum=dto.getQuantity();
                if(goodsSale.getMemberNum()!=null){
                    //累计会员以往订单数量
                    memberBuyNum=NumberUtil.add(memberBuyNum, goodsSale.getMemberNum());
                }
                //个人限购校验
                tempNum=memberBuyNum-(resp.getRestrictNum().doubleValue());
                if(tempNum>maxDiffNum){
                    maxDiffNum=tempNum;
                    restrictType=1;
                }

                Double totalBuyNum=dto.getQuantity();
                if(goodsSale.getTotalSales()!=null){
                    totalBuyNum = NumberUtil.add(totalBuyNum, goodsSale.getTotalSales());
                }
                //活动限购校验
                tempNum=totalBuyNum-(resp.getRestrictTotalNum().doubleValue());
                if(tempNum>maxDiffNum){
                    maxDiffNum=tempNum;
                    restrictType=2;
                }
            }

            if(maxDiffNum>0){
                double enableNum=dto.getQuantity()-maxDiffNum;
                enableNum=NumberUtil.round(enableNum,2,RoundingMode.DOWN).doubleValue();
                if(GoodsQuantityCheckTypeEnum.ADJUST_NUM.equals(checkTypeEnum)||GoodsQuantityCheckTypeEnum.CALCULATE_PRICE.equals(checkTypeEnum)){
                    return enableNum;
                }else{
                    if(restrictType==1){
                        //已超个人限购
                        throw buildResponseCode(enableNum);
                    }else{
                        //已超活动限购
                        throw buildResponseCode(enableNum);
                    }
                }
            }
        }
        return -1d;
    }

    /**
     * 1记录sku参与的活动，以及活动优惠金额（单件与总优惠(满减无法整除的)）
     * @param dto
     * @param act
     * @param salePrice 单价优惠金额
     * @param saleTotalAmount sku总优惠金额
     */
    private void recordJoinActivity(CartActivityPriceDto dto,ActivityGoodsBO act,Double salePrice,Double saleTotalAmount){
        recordJoinActivityAll(dto,act,salePrice,saleTotalAmount,null);
    }

    /**
     * 2记录sku参与的活动，以及活动优惠金额（单件与总优惠(满减无法整除的)）
     * @param dto
     * @param act
     * @param salePrice
     * @param saleTotalAmount
     * @param fullMoneyAmount
     */
    private void recordJoinActivityAll(CartActivityPriceDto dto,ActivityGoodsBO act,Double salePrice,Double saleTotalAmount,Double fullMoneyAmount){
        List<SkuJoinActivityResponse> activityList = dto.getActivityList();
        //记录当前sku参与的活动
        if (activityList == null) {
            activityList = new ArrayList<>();
            dto.setActivityList(activityList);
        }
        SkuJoinActivityResponse skuJoinActivityResponse = new SkuJoinActivityResponse();
        skuJoinActivityResponse.setBelongType(act.getBelongType());
        skuJoinActivityResponse.setActivityId(act.getActivityId());
        skuJoinActivityResponse.setSalePrice(salePrice);
        skuJoinActivityResponse.setSaleTotalAmount(saleTotalAmount);
        skuJoinActivityResponse.setFullMoneyAmount(fullMoneyAmount);
        skuJoinActivityResponse.setActivityType(act.getActivityType());
        skuJoinActivityResponse.setActivityName(act.getActivityName());
        skuJoinActivityResponse.setStartTime(act.getStartTime());
        skuJoinActivityResponse.setEndTime(act.getEndTime());
        activityList.add(skuJoinActivityResponse);
    }

    /**
     * 计算叠加权益商品价
     * @param dto
     * @param memberPriceRight
     */
    private void calculateBasePrice(CartActivityPriceDto dto,Map<String, Double> memberPriceRight){
        boolean isPriceSale = false;
        Double tempPrice = 0d;
        if(CollectionUtil.isNotEmpty(dto.getEnableActivityList())) {
            for (ActivityGoodsBO act : dto.getEnableActivityList()) {
                //单件优惠(特价、直降、折扣)
                if (ActivityTypeEnum.isPriceSaleActivityType(act.getActivityType())) {
                    isPriceSale = true;
                    tempPrice = act.getActivityPrice().doubleValue();
                    //计算单件优惠金额
                    Double salePrice = NumberUtil.sub(dto.getGoodsPrice(), tempPrice);
                    //记录当前sku参与的活动
                    recordJoinActivity(dto,act,salePrice,NumberUtil.mul(salePrice,dto.getQuantity()));
                    break;
                }
            }
        }
        //未参与单价活动的商品，取策略价或原价
        if (!isPriceSale) {
            tempPrice = dto.getGoodsPrice();
        }
        //获取当前sku归属供应商的权益参数
        Double priceRight = 1D;
        //判断商品是否允许会员价购买
        if(dto.getIsMemberPrice()!=null&&dto.getIsMemberPrice()){
            Double priceRightFeign = memberPriceRight.get(dto.getUpperMemberId() + "_" + dto.getUpperRoleId());
            if(priceRightFeign!=null){
                priceRight=priceRightFeign;
            }
        }
        //设置叠加权益参数后的商品价格
        double superpositionPrice = NumberUtil.mul(tempPrice, priceRight);
        dto.setBasePrice(superpositionPrice);
        dto.setParameter(priceRight);
        if(isPriceSale) {
            dto.setHandPrice(superpositionPrice);
        }
    }

    private Double getLadderStar(String ladder){
        if(ladder==null){return 0D;}
        return Double.parseDouble(ladder.split("-")[0]);
    }

    /**
     * 匹配满额或满量阶梯
     * @param comparisonObj
     * @param ladderDtoList
     * @return
     */
    private BigDecimal matchLadder(BigDecimal comparisonObj,List<LadderDto> ladderDtoList){
        if(CollectionUtil.isEmpty(ladderDtoList)){
            log.warn("满量或满额阶梯值未设置");
            return null;
        }
        //排序
        ladderDtoList.sort(Comparator.comparing(LadderDto::getKey));
        BigDecimal result=null;
        for(LadderDto ladder :ladderDtoList){
            if(comparisonObj.compareTo(ladder.getKey())>=0){
                result=ladder.getValue();
            }
        }
        log.info("------matchLadder-------result:{},comparisonObj:{},ladderDtoList:{}",result,comparisonObj,JSONUtil.toJsonStr(ladderDtoList));
        return result;
    }

    /**
     * 获得多件匹配阶梯后的优惠总金额
     * @param comparisonObj
     * @param ladderDtoList
     * @param basePrice
     * @return 比如购买5件，匹配3个阶梯，返回金额为3个阶梯优惠总金额
     */
    private BigDecimal matchMorePieceLadder(BigDecimal comparisonObj,List<LadderDto> ladderDtoList,BigDecimal basePrice){
        if(CollectionUtil.isEmpty(ladderDtoList)){
            log.warn("多件促销阶梯值未设置");
            return null;
        }
        //排序
        ladderDtoList.sort(Comparator.comparing(LadderDto::getKey));
        //记录累计匹配的阶梯优惠总额
        BigDecimal result=new BigDecimal(0);
        for(LadderDto ladder :ladderDtoList){
            if(comparisonObj.compareTo(ladder.getKey())>=0){
                result=result.add(NumberUtil.sub(BigDecimal.valueOf(100D),ladder.getValue()).multiply(BigDecimal.valueOf(0.01D)).multiply(basePrice));
            }
        }
        log.info("------matchMorePieceLadder-------result:{},comparisonObj:{},ladderDtoList:{},basePrice:{}",result,comparisonObj,JSONUtil.toJsonStr(ladderDtoList),basePrice);
        return result;
    }

    /**
     * 计算满额与满量[与组合计算相似]
     * @param dtoList
     */
    private void calculateFullCondition(List<CartActivityPriceDto> dtoList){
        //保存参与满额活动的商品总金额
        Map<String,SkuAmountDto> fullMoneyMap=new HashMap<>();
        //计算满量到手价或记录满额商品
        for(CartActivityPriceDto dto : dtoList) {
            //排除赠品与换购的计算
            if (dto.getParentSkuId() == null) {
                if (CollectionUtil.isNotEmpty(dto.getEnableActivityList())) {

                    for (ActivityGoodsBO act : dto.getEnableActivityList()) {

                        if (ActivityTypeEnum.FULL_QUANTITY.getCode().equals(act.getActivityType())) {
                            //满量
                            FullQuantityBO fullQuantityBO = (FullQuantityBO) act.getActivityDefined();
                            List<LadderDto> ladderDtoList = fullQuantityBO.getLadderList().stream().map(o -> {
                                LadderDto ladderDto = new LadderDto();
                                BeanUtils.copyProperties(o, ladderDto);
                                return ladderDto;
                            }).collect(Collectors.toList());
                            //获得匹配的阶梯参数
                            BigDecimal ladderVal = matchLadder(BigDecimal.valueOf(dto.getQuantity()), ladderDtoList);
                            if (ladderVal == null) {
                                continue;
                            }
                            if (fullQuantityBO.getType() == 1) {
                                //满量减  单价优惠=总优惠÷数量
                                Double discountAmount = NumberUtil.div(ladderVal.doubleValue(), dto.getQuantity().doubleValue(), 3, RoundingMode.HALF_UP);
                                dto.setHandPrice(NumberUtil.sub(dto.getBasePrice(), discountAmount));
                                recordJoinActivity(dto, act, discountAmount, ladderVal.doubleValue());
                            } else if (fullQuantityBO.getType() == 2) {
                                //满量折  单价优惠=（基础价*（100-折扣）/100）
                                Double discountAmount = NumberUtil.mul(dto.getBasePrice(), NumberUtil.sub(BigDecimal.valueOf(100D), ladderVal).multiply(BigDecimal.valueOf(0.01D))).doubleValue();
                                dto.setHandPrice(NumberUtil.sub(dto.getBasePrice(), discountAmount));
                                recordJoinActivity(dto, act, discountAmount, NumberUtil.mul(discountAmount, dto.getQuantity()));
                            }
                        } else if (ActivityTypeEnum.FULL_MONEY.getCode().equals(act.getActivityType())) {
                            //满额（额是指:直降优惠叠加权益参数得到的基础价格*购买数量得到的总额）
                            //记录参与满额的活动的sku
                            String key = act.getBelongType() + "_" + act.getActivityId();
                            SkuAmountDto skuAmountDto = fullMoneyMap.get(key);
                            Double skuAmount = NumberUtil.mul(dto.getBasePrice(), dto.getQuantity());
                            if(skuAmountDto==null){
                                skuAmountDto=new SkuAmountDto();
                                skuAmountDto.setAmount(skuAmount);
                                skuAmountDto.setNum(1);
                                fullMoneyMap.put(key,skuAmountDto);
                            }else{
                                skuAmountDto.setAmount(NumberUtil.add(skuAmountDto.getAmount(),skuAmount));
                                skuAmountDto.setNum(skuAmountDto.getNum()+1);
                            }

                        }
                    }

                }

            }
        }

        //再次循环，计算满额
        if(fullMoneyMap.size()>0){
            for(CartActivityPriceDto dto : dtoList) {
                //排除赠品与换购的计算
                if (dto.getParentSkuId() == null) {
                    for (ActivityGoodsBO act : dto.getEnableActivityList()) {
                        if (ActivityTypeEnum.FULL_MONEY.getCode().equals(act.getActivityType())) {
                            FullMoneyBO fullMoneyBO = (FullMoneyBO) act.getActivityDefined();
                            List<LadderDto> ladderDtoList = fullMoneyBO.getLadderList().stream().map(o -> {
                                LadderDto ladderDto = new LadderDto();
                                BeanUtils.copyProperties(o, ladderDto);
                                return ladderDto;
                            }).collect(Collectors.toList());
                            //参与该活动的商品总金额
                            SkuAmountDto skuTotalAmount = fullMoneyMap.get(act.getBelongType() + "_" + act.getActivityId());
                            //获得匹配的阶梯参数
                            BigDecimal ladderVal = matchLadder(BigDecimal.valueOf(skuTotalAmount.getAmount()), ladderDtoList);
                            if (ladderVal == null) {
                                continue;
                            }
                            if (fullMoneyBO.getType() == 1) {
                                //满额减  单价优惠=总优惠÷数量
                                //得到当前sku基础总额
                                Double currentSku = NumberUtil.mul(dto.getBasePrice(), dto.getQuantity());
                                //当前sku金额占比 基础价*数量/该活动商品总金额
                                double ratio = NumberUtil.div(currentSku, skuTotalAmount.getAmount(),2);
                                //当前sku总优惠
                                BigDecimal skuTotalDiscountAmount = NumberUtil.mul(BigDecimal.valueOf(ratio), ladderVal);
                                double actDiscountAmount = skuTotalAmount.getDiscountAmount() == null ? 0D : skuTotalAmount.getDiscountAmount();
                                if(skuTotalAmount.getNum()==1){
                                    skuTotalDiscountAmount =ladderVal.subtract(BigDecimal.valueOf(actDiscountAmount));
                                }
                                skuTotalAmount.setDiscountAmount(NumberUtil.add(actDiscountAmount,skuTotalDiscountAmount).doubleValue());
                                skuTotalAmount.setNum(skuTotalAmount.getNum()-1);
                                //得到单价优惠  ratio*优惠总额/当前sku数量
                                Double discountAmount =skuTotalDiscountAmount.divide(BigDecimal.valueOf(dto.getQuantity()),3,RoundingMode.HALF_UP).doubleValue();
                                dto.setHandPrice(NumberUtil.sub(dto.getBasePrice(), discountAmount));
                                recordJoinActivityAll(dto, act, discountAmount, skuTotalDiscountAmount.doubleValue(),ladderVal.doubleValue());
                            } else if (fullMoneyBO.getType() == 2) {
                                //满额折  单价优惠=（基础价*（100-折扣）/100）
                                Double discountAmount = NumberUtil.mul(dto.getBasePrice(), NumberUtil.sub(BigDecimal.valueOf(100D), ladderVal).multiply(BigDecimal.valueOf(0.01D))).doubleValue();
                                dto.setHandPrice(NumberUtil.sub(dto.getBasePrice(), discountAmount));
                                recordJoinActivity(dto, act, discountAmount, NumberUtil.mul(discountAmount, dto.getQuantity()));
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 计算多件
     * @param dto
     */
    private void calculateMorePiece(CartActivityPriceDto dto){
        //排除赠品与换购的计算
        if (dto.getParentSkuId() == null) {
            if (CollectionUtil.isNotEmpty(dto.getEnableActivityList())) {
                for (ActivityGoodsBO act : dto.getEnableActivityList()) {
                    if (ActivityTypeEnum.MORE_PIECE.getCode().equals(act.getActivityType())) {
                        MorePieceBO morePieceBO = (MorePieceBO) act.getActivityDefined();
                        List<LadderDto> ladderDtoList = morePieceBO.getLadderList().stream().map(o -> {
                            LadderDto ladderDto = new LadderDto();
                            ladderDto.setKey(o.getNum());
                            ladderDto.setValue(o.getDiscount());
                            return ladderDto;
                        }).collect(Collectors.toList());
                        //计算匹配阶梯后的优惠总额
                        BigDecimal ladderVal = matchMorePieceLadder(BigDecimal.valueOf(dto.getQuantity()), ladderDtoList, BigDecimal.valueOf(dto.getBasePrice()));
                        if(ladderVal != null&&ladderVal.compareTo(BigDecimal.ZERO)!=0){
                            Double discountAmount =ladderVal.divide(BigDecimal.valueOf(dto.getQuantity()),3,RoundingMode.HALF_UP).doubleValue();
                            dto.setHandPrice(NumberUtil.sub(dto.getBasePrice(), discountAmount));
                            recordJoinActivity(dto, act, discountAmount,ladderVal.doubleValue());
                        }
                    }
                }
            }
        }
    }

    /**
     * 计算组合[与满额、满量相似]
     * @param dtoList
     */
    private void calculateCombination(List<CartActivityPriceDto> dtoList){
        //保存参与组合活动的商品总数量
        Map<String, CombinationDto> fullMoneyMap=new HashMap<>();
        //记录参与组合的商品
        for(CartActivityPriceDto dto : dtoList) {
            //排除赠品与换购的计算
            if (dto.getParentSkuId() == null) {
                if (CollectionUtil.isNotEmpty(dto.getEnableActivityList())) {
                    for (ActivityGoodsBO act : dto.getEnableActivityList()) {
                        if (ActivityTypeEnum.COMBINATION.getCode().equals(act.getActivityType())) {
                            //满额（额是指:直降优惠叠加权益参数得到的基础价格*购买数量得到的总额）
                            //记录参与满额的活动的sku
                            String key = act.getBelongType() + "_" + act.getActivityId();
                            CombinationDto combinationDto = fullMoneyMap.get(key);
                            Double skuQuantity = dto.getQuantity();
                            double skuAmount = NumberUtil.mul(dto.getBasePrice(), dto.getQuantity());
                            if(combinationDto==null){
                                combinationDto=new CombinationDto();
                                combinationDto.setNum(BigDecimal.valueOf(skuQuantity));
                                combinationDto.setSkuAmount(BigDecimal.valueOf(skuAmount));
                                combinationDto.setSkuNum(1);
                                fullMoneyMap.put(key,combinationDto);
                            }else{
                                combinationDto.setNum(combinationDto.getNum().add(BigDecimal.valueOf(skuQuantity)));
                                combinationDto.setSkuAmount(combinationDto.getSkuAmount().add(BigDecimal.valueOf(skuAmount)));
                                combinationDto.setSkuNum(combinationDto.getSkuNum()+1);
                            }
                        }
                    }
                }
            }
        }

        //再次循环，计算组合
        if(fullMoneyMap.size()>0){
            for(CartActivityPriceDto dto : dtoList) {
                //排除赠品与换购的计算
                if (dto.getParentSkuId() == null) {
                    for (ActivityGoodsBO act : dto.getEnableActivityList()) {
                        if (ActivityTypeEnum.COMBINATION.getCode().equals(act.getActivityType())) {
                            CombinationBO combinationBO = (CombinationBO) act.getActivityDefined();
                            //参与该活动的商品总金额
                            CombinationDto combinationDto = fullMoneyMap.get(act.getBelongType() + "_" + act.getActivityId());
                            //不够数量则跳过
                            if (combinationDto.getNum().compareTo(BigDecimal.valueOf(combinationBO.getNum()))>0) {
                                throw new BusinessException(ResponseCode.MARKETING_ACTIVITY_GT_COMBINATION_COUNT);
                            }else if(combinationDto.getNum().compareTo(BigDecimal.valueOf(combinationBO.getNum()))<0){
                                continue;
                            }
                            //sku占比 当前sku金额/组合商品总额
                            double currentSKuAmount = NumberUtil.mul(dto.getQuantity(), dto.getBasePrice());
                            double ratio=NumberUtil.div(currentSKuAmount,combinationDto.getSkuAmount().doubleValue(),3,RoundingMode.HALF_UP);
                            double skuPayAmount = NumberUtil.mul(ratio, combinationBO.getPrice().doubleValue());
                            double payAmount = combinationDto.getPayAmount() == null ? 0D : combinationDto.getPayAmount();
                            //当前sku总优惠   当前sku总额-sku需付金额(占比*组合需付金额)=当前sku总优惠
                            double skuDiscountAmount=NumberUtil.sub(currentSKuAmount,skuPayAmount);
                            //跳过优惠不及原价基础价格的数据
                            if(skuDiscountAmount<=0){
                                log.info("组合优惠金额小于或等于商品基础优惠");
                                continue;
                            }
                            if(combinationDto.getSkuNum()==1){
                                skuPayAmount=combinationBO.getPrice().subtract(BigDecimal.valueOf(payAmount)).doubleValue();
                                skuDiscountAmount=NumberUtil.sub(currentSKuAmount,skuPayAmount);
                            }
                            combinationDto.setPayAmount(NumberUtil.add(payAmount,skuPayAmount));
                            combinationDto.setSkuNum(combinationDto.getSkuNum()-1);
                            //当前sku单件优惠   当前sku总优惠/数量
                            Double discountAmount =NumberUtil.div(skuDiscountAmount,dto.getQuantity().doubleValue(),3,RoundingMode.HALF_UP);
                            dto.setHandPrice(NumberUtil.sub(dto.getBasePrice(), discountAmount));
                            //活动总优惠  商品总额-组合需付金额=活动总优惠
                            double activityDiscountAmount = combinationDto.getSkuAmount().subtract(combinationBO.getPrice()).doubleValue();
                            recordJoinActivityAll(dto, act, discountAmount,skuDiscountAmount,activityDiscountAmount);
                        }
                    }
                }
            }
        }
    }

    private String getSwapKey(CartActivityPriceDto dto){
        return dto.getSkuId()+"_"+dto.getParentSkuId();
    }

    /**
     * 计算换购
     * @param dtoList
     * @param swapActivityMap
     */
    private void calculateSwap(List<CartActivityPriceDto> dtoList, Map<String, ActivityGoodsSubsidiaryDto> swapActivityMap) {
        //遍历，得到匹配的换购阶梯价格与数量
        for(CartActivityPriceDto dto : dtoList){
            //排除赠品与换购的计算
            if(dto.getParentSkuId()==null) {
                for(String skuKey:swapActivityMap.keySet()){
                    //skuKey格式：换购商品skuid_活动商品skuid
                    String[] skuKeys = skuKey.split("_");
                    if(skuKey.endsWith("_"+dto.getSkuId())){
                        List<ActivityGoodsBO> enableActivityList = dto.getEnableActivityList();
                        //过滤得到换购活动
                        ActivityGoodsBO swap=null;
                        for(ActivityGoodsBO act:enableActivityList){
                            if(ActivityTypeEnum.SWAP.getCode().equals(act.getActivityType())){
                                if(swap!=null){
                                    log.warn("存在sku多次参与了换购活动了");
                                }
                                swap=act;
                            }
                        }
                        if(swap==null){
                            continue;
                        }
                        SwapBO swapBO=(SwapBO)swap.getActivityDefined();
                        //根据活动所属类型，活动id，商品skuid, 换购商品id，查询换购阶梯条件
                        List<ActivityGoodsSubsidiaryDto> activityGoodsSubsidiaryDtos = activityGoodsCacheService.selectSkuSwapActivityLadder(swap.getBelongType(), swap.getActivityId(), dto.getSkuId(), Long.parseLong(skuKeys[0]));
                        if(CollectionUtil.isNotEmpty(activityGoodsSubsidiaryDtos)) {
                            //排序
                            activityGoodsSubsidiaryDtos.sort(Comparator.comparing(ActivityGoodsSubsidiaryDto::getLimitValue));
                            if (swapBO.getSwapType() == 1) {
                                //满额换购
                                BigDecimal skuAmount = BigDecimal.valueOf(NumberUtil.mul(dto.getQuantity(), dto.getBasePrice()));
                                for(ActivityGoodsSubsidiaryDto subsidiaryDto :activityGoodsSubsidiaryDtos){
                                    if(skuAmount.compareTo(subsidiaryDto.getLimitValue())>=0){
                                        subsidiaryDto.setActivityGoodsBO(swap);
                                        swapActivityMap.put(skuKey,subsidiaryDto);
                                    }
                                }
                            } else {
                                //满量换购
                                for(ActivityGoodsSubsidiaryDto subsidiaryDto :activityGoodsSubsidiaryDtos){
                                    if(BigDecimal.valueOf(dto.getQuantity()).compareTo(subsidiaryDto.getLimitValue())>=0){
                                        subsidiaryDto.setActivityGoodsBO(swap);
                                        swapActivityMap.put(skuKey,subsidiaryDto);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        //计算换购的到手价
        for(CartActivityPriceDto dto : dtoList){
            //遍历换购商品
            if(dto.getParentSkuId() !=null) {
                String key=getSwapKey(dto);
                ActivityGoodsSubsidiaryDto subsidiaryDto = swapActivityMap.get(key);
                if(subsidiaryDto!=null){
                    Double goodsPrice = dto.getBasePrice() == null ? dto.getGoodsPrice() : dto.getBasePrice();
                    Double discountAmount =NumberUtil.sub(goodsPrice.doubleValue(),subsidiaryDto.getSwapPrice().doubleValue());
                    Double skuDiscountAmount=NumberUtil.mul(dto.getQuantity(),discountAmount);
                    dto.setHandPrice(subsidiaryDto.getSwapPrice().doubleValue());
                    if(subsidiaryDto.getNum().compareTo(BigDecimal.valueOf(dto.getQuantity()))<0) {
                        dto.setEnableQuantity(subsidiaryDto.getNum().doubleValue());
                    }
                    //活动总优惠  商品总额-组合需付金额=活动总优惠
                    recordJoinActivity(dto, subsidiaryDto.getActivityGoodsBO(), discountAmount,skuDiscountAmount);
                }
            }
        }
    }

    /**
     * 匹配赠品阶梯列表
     * @param cartGiveResponses
     * @param compareVal
     * @param giftType 赠品类型：1-赠商品 2-赠优惠卷
     * @return
     */
    private List<CartGiveResponse> matchGiftLadderList(List<CartGiveResponse> cartGiveResponses, Double compareVal, Integer giftType){
        List<CartGiveResponse> cartGiveResponseList =new ArrayList<>();
        Integer groupNo=null;
        //排序
        cartGiveResponses.sort(Comparator.comparing(CartGiveResponse::getLimitValue));
        for(CartGiveResponse ga: cartGiveResponses){
            if(BigDecimal.valueOf(compareVal).compareTo(ga.getLimitValue())>=0){
                //不同阶梯值时，清空list
                if(cartGiveResponseList.size()>0&&!groupNo.equals(ga.getGroupNo())){
                    cartGiveResponseList.clear();
                }
                ga.setGiftType(giftType);
                cartGiveResponseList.add(ga);
                //记录上一次的阶梯值
                groupNo=ga.getGroupNo();
            }
        }
        return cartGiveResponseList;
    }

    /**
     * 匹配加载赠品列表
     * @param dtoList
     */
    private void loadGiftList(List<CartActivityPriceDto> dtoList){
        for(CartActivityPriceDto dto : dtoList){
            //排除赠品与换购的计算
            if(dto.getParentSkuId()==null) {
                List<ActivityGoodsBO> enableActivityList = dto.getEnableActivityList();
                if(CollectionUtil.isNotEmpty(enableActivityList)){
                    for(ActivityGoodsBO act :enableActivityList){
                        if(ActivityTypeEnum.GIVE.getCode().equals(act.getActivityType())){
                            GiveBO giveBO=(GiveBO) act.getActivityDefined();
                            List<CartGiveResponse> cartGiveResponseList =null;
                            if(giveBO.getGiftType()==1){
                                //赠商品
                                List<CartGiveResponse> cartGiveResponses = activityGoodsCacheService.selectSkuGiveProductList(act.getBelongType(), act.getActivityId(), dto.getSkuId());
                                if(CollectionUtil.isEmpty(cartGiveResponses)){
                                    log.warn("赠送促销未设置赠送商品的信息");
                                }
                                //赠送促销类型：1-满额赠 2-买商品赠
                                if(giveBO.getGiveType()==1){
                                    //满额
                                    Double skuAmount=NumberUtil.mul(dto.getQuantity(),dto.getBasePrice());
                                    cartGiveResponseList = matchGiftLadderList(cartGiveResponses, skuAmount,1);
                                }else if(giveBO.getGiveType()==2){
                                    //满量
                                    cartGiveResponseList = matchGiftLadderList(cartGiveResponses, dto.getQuantity(),1);
                                }
                            }else if(giveBO.getGiftType()==2){
                                //赠优惠券
                                List<CartGiveResponse> cartGiveResponses = activityGoodsCacheService.selectSkuGiveCouponList(act.getBelongType(), act.getActivityId(), dto.getSkuId());
                                if(CollectionUtil.isEmpty(cartGiveResponses)){
                                    log.warn("赠送促销未设置赠送优惠券的信息");
                                }
                                //赠送促销类型：1-满额赠 2-买商品赠
                                if(giveBO.getGiveType()==1){
                                    //满额
                                    Double skuAmount=NumberUtil.mul(dto.getQuantity(),dto.getBasePrice());
                                    cartGiveResponseList = matchGiftLadderList(cartGiveResponses, skuAmount,2);
                                }else if(giveBO.getGiveType()==2){
                                    //满量
                                    cartGiveResponseList = matchGiftLadderList(cartGiveResponses, dto.getQuantity(),2);
                                }
                            }
                            if(CollectionUtil.isNotEmpty(cartGiveResponseList)){
                                dto.setGiveList(cartGiveResponseList);
                                recordJoinActivity(dto,act,null,null);
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 是否忽略参与活动
     * @param activityType
     * @param list
     * @return
     */
    private boolean isIgnoreActivity(Integer activityType,List<CartNotJoinActivityDTO> list){
        return CollectionUtil.isNotEmpty(list)&&list.stream().map(o ->o.getActivityType()).collect(Collectors.toList()).contains(activityType);
    }

    /**
     * 加载套餐信息
     * @param dtoList
     */
    private void loadSetMealList(List<CartActivityPriceDto> dtoList){
        for(CartActivityPriceDto dto : dtoList){
            //排除赠品与换购的计算
            if(dto.getParentSkuId()==null) {
                List<ActivityGoodsBO> enableActivityList = dto.getEnableActivityList();
                if(CollectionUtil.isNotEmpty(enableActivityList)&&!isIgnoreActivity(ActivityTypeEnum.SET_MEAL.getCode(), dto.getNotJoinList())){
                    for(ActivityGoodsBO act :enableActivityList){
                        if(ActivityTypeEnum.SET_MEAL.getCode().equals(act.getActivityType())){
                            if(dto.getGroupNo()==null){
                                throw new BusinessException(ResponseCode.MARKETING_ACTIVITY_GROUP_NO_IS_REQUIRED);
                            }else if(dto.getQuantity().intValue()!= dto.getQuantity()){
                                throw new BusinessException(ResponseCode.MARKETING_ACTIVITY_GROUP_GOODS_NUM_NOT_INCLUDE_DECIMALS);
                            }
                            List<SubsidiaryDto> subsidiaryDtos = activityGoodsCacheService.selectSkuSetMealList(act.getBelongType(), act.getActivityId(), dto.getSkuId(), dto.getGroupNo());
                            if(CollectionUtil.isEmpty(subsidiaryDtos)){
                                throw new BusinessException(ResponseCode.MARKETING_ACTIVITY_GROUP_NO_NOT_EXISTS);
                            }
                            //套餐到手价
                            Double groupHandPrice=subsidiaryDtos.get(0).getGroupPrice().doubleValue();
                            dto.setGroupHandPrice(groupHandPrice);
                            //套餐总到手额
                            Double totalGroupHandPrice=NumberUtil.mul(groupHandPrice.doubleValue(),dto.getQuantity().intValue());
                            //商品原价总额
                            Double skuTotalAmount= NumberUtil.mul(dto.getQuantity(),dto.getGoodsPrice());
                            for(SubsidiaryDto sub :subsidiaryDtos){
                                //子商品的数量*主商品的套数=子商品的购买数
                                double skuNum=NumberUtil.mul(sub.getNum().doubleValue(),dto.getQuantity().doubleValue());
                                sub.setNum(BigDecimal.valueOf(skuNum));
                                Double itemAmount=NumberUtil.mul(sub.getNum().doubleValue(),sub.getPrice().doubleValue());
                                skuTotalAmount=NumberUtil.add(skuTotalAmount,itemAmount);
                            }

                            double subTotalHandPrice=0d;
                            //设置套餐子商品到手价
                            for(SubsidiaryDto sub :subsidiaryDtos){
                                //原商品总额=原价*数量
                                Double itemAmount=NumberUtil.mul(sub.getNum().doubleValue(),sub.getPrice().doubleValue());
                                //到手价=(原商品总额/套餐商品总额)*到手价
                                double itemHandPrice = NumberUtil.mul(NumberUtil.div(itemAmount, skuTotalAmount,3,RoundingMode.HALF_UP), totalGroupHandPrice.doubleValue());
                                subTotalHandPrice=NumberUtil.add(subTotalHandPrice,itemHandPrice);
                                sub.setHandPrice(BigDecimal.valueOf(NumberUtil.div(itemHandPrice,sub.getNum().doubleValue(),2,RoundingMode.HALF_UP)));
                            }
                            //主商品到手价
                            dto.setHandPrice(NumberUtil.div(NumberUtil.sub(totalGroupHandPrice.doubleValue(),subTotalHandPrice),dto.getQuantity().doubleValue(),2,RoundingMode.HALF_UP));
                            dto.setSetMealList(subsidiaryDtos);
                            //记录参与的活动
                                //主商品单价优惠
                                // double discoutAmount = NumberUtil.mul(NumberUtil.sub(dto.getGoodsPrice(), dto.getHandPrice()), dto.getQuantity().doubleValue());
                            recordJoinActivity(dto,act,null,NumberUtil.sub(skuTotalAmount,totalGroupHandPrice));
                        }
                    }
                }
            }
        }
    }

    /**
     * 获得商品阶梯价
     * @param stringDoubleMap
     * @param quantity
     * @return
     */
    private Double getGoodsLadderPrice(Map<String, Double> stringDoubleMap,Double quantity){
        Set<String> keySet = stringDoubleMap.keySet();
        //排序
        List<String> keyList = keySet.stream().sorted(Comparator.comparing(this::getLadderStar)).collect(Collectors.toList());
        Double lastEndPrice=null;//记录上一次的闭区间
        Double price=null;
        for (String ladderKey :keyList){
            String[] ladderArray = ladderKey.split("-");
            Double startPrice=Double.parseDouble(ladderArray[0]);
            Double endPrice=Double.parseDouble(ladderArray[1]);
            //处于区间间歇中，退出循环
            if(lastEndPrice!=null&&quantity.compareTo(lastEndPrice)>0&&quantity.compareTo(startPrice)<0){
                break;
            }
            //正好匹配当前区间
            if(quantity.compareTo(endPrice)<=0){
                price=stringDoubleMap.get(ladderKey);
                break;
            }
            //大于当前区间最大值
            if(quantity.compareTo(endPrice)>0){
                price=stringDoubleMap.get(ladderKey);
            }
            lastEndPrice=endPrice;
        }
        log.info("阶梯价：{},quantity:{},map:{}",price,quantity,JSONUtil.toJsonStr(stringDoubleMap));
        return price;
    }

    /**
     * 判断当前时间，是否为秒杀时段内
     * @param secKillBO
     * @return
     */
    private boolean isKillTime(SecKillBO secKillBO){
        int nowSec=DateTimeUtil.getNowSecOfHHmmss();
        return DateTimeUtil.getNowSecOfHHmmss(secKillBO.getStartTime())<nowSec&&DateTimeUtil.getNowSecOfHHmmss(secKillBO.getEndTime())>nowSec;
    }

    /**
     * 计算秒杀商品价
     * @param dto
     */
    private void calculateSecKill(CartActivityPriceDto dto){
        for (ActivityGoodsBO act : dto.getEnableActivityList()) {
            if (ActivityTypeEnum.SEC_KILL.getCode().equals(act.getActivityType())) {
                SecKillBO secKillBO =(SecKillBO) act.getActivityDefined();
                //秒杀时间段内才能秒杀价格
                if(isKillTime(secKillBO)){
                    Double salePrice=NumberUtil.sub(dto.getGoodsPrice().doubleValue(),act.getActivityPrice().doubleValue());
                    dto.setHandPrice(act.getActivityPrice().doubleValue());
                    //重置会员折扣
                    dto.setParameter(1D);
                    //记录当前sku参与的活动
                    recordJoinActivity(dto,act,salePrice,NumberUtil.mul(salePrice,dto.getQuantity()));
                    break;
                }
            }
        }
    }

    /**
     * 到手价计算入口
     * @param loginUser
     * @param req
     * @return
     */
    private List<CartActivityPriceDto> calculateActivityPriceFinal(UserLoginCacheDTO loginUser, List<CartActivityPriceRequest> req,GoodsQuantityCheckTypeEnum checkTypeEnum){
        //入参转dto
        List<CartActivityPriceDto> dtoList = req.stream().map(o -> {
            CartActivityPriceDto dto = new CartActivityPriceDto();
            BeanUtils.copyProperties(o, dto);
            if(CollectionUtil.isNotEmpty(o.getNotJoinList())){
                List<CartNotJoinActivityDTO> notJoinActivityDTOS = o.getNotJoinList().stream().map(nj -> {
                    CartNotJoinActivityDTO cnjDTO = new CartNotJoinActivityDTO();
                    cnjDTO.setActivityType(nj.getActivityType());
                    return cnjDTO;
                }).collect(Collectors.toList());
                dto.setNotJoinList(notJoinActivityDTOS);
            }
            return dto;
        }).collect(Collectors.toList());
        log.info("-------入参----------memberId:{},roleId:{} dtoList:{}", loginUser.getMemberId(),loginUser.getMemberRoleId(),JSONUtil.toJsonStr(dtoList));
        //1查询商品的基础价格(策略价/原价)
        Map<Long, CommodityPriceResponse> skuPriceMap= getGoodsPrice(dtoList,loginUser.getMemberId(),loginUser.getMemberRoleId());
        dtoList.forEach(o ->{
            CommodityPriceResponse commodityPriceResponse = skuPriceMap.get(o.getSkuId());
            if(commodityPriceResponse!=null){
                o.setIsMemberPrice(commodityPriceResponse.getIsMemberPrice());
                Map<String, Double> stringDoubleMap = commodityPriceResponse.getCommodityPrice();
                if(stringDoubleMap!=null) {
                    Double price = stringDoubleMap.get("0-0");
                    if (price != null) {
                        o.setFlag(false);
                    } else {
                        price = getGoodsLadderPrice(stringDoubleMap, o.getQuantity());
                    }
                    o.setGoodsPrice(price);
                }
            }
        });
        log.info("-------1----------:{}", JSONUtil.toJsonStr(dtoList));

        //2查询商品参与的所有活动
         //记录本次所有活动类型
        Set<Integer> activityTypeSet=new HashSet<>();
        Map<String,ActivityGoodsSubsidiaryDto> swapActivityMap=new HashMap<>();//记录换购商品id
        for(CartActivityPriceDto dto :dtoList) {
            List<ActivityGoodsBO> skuAllActivityList = activityPriceCalculateComponent.getSkuAllActivityList(dto.getShopId(), dto.getSkuId(), new MemberAndRoleIdBO(loginUser.getMemberId(), loginUser.getMemberRoleId()));
            dto.setEnableActivityList(skuAllActivityList);
            List<Integer> enableActivityTypeList = skuAllActivityList.stream().map(ActivityGoodsBO::getActivityType).collect(Collectors.toList());
            //过滤sku不参与的活动
            if(CollectionUtil.isNotEmpty(dto.getNotJoinList())){
                List<Integer> notJoinList = dto.getNotJoinList().stream().map(CartNotJoinActivityDTO::getActivityType).collect(Collectors.toList());
                enableActivityTypeList.removeIf(notJoinList::contains);
            }
            activityTypeSet.addAll(enableActivityTypeList);
            if(dto.getParentSkuId()!=null) {
                //记录换购商品id
                swapActivityMap.put(getSwapKey(dto), null);
            }
        }
        log.info("-------2----------:{}", JSONUtil.toJsonStr(dtoList));

        //2.2校验购买数量是否超限
        List<Long> activityIds = dtoList.stream().flatMap(o -> o.getEnableActivityList().stream().map(ActivityGoodsBO::getActivityId)).collect(Collectors.toList());
        List<Long> skuIds = getSkuIdExcludeSwap(dtoList);
        Map<String, ActivityGoodsRestrictNumResp> activityGoodsRestrictNum = activityGoodsCacheService.getActivityGoodsRestrictNum(activityIds, skuIds);
        //是否超限
        boolean isOverrun=false;
        for(CartActivityPriceDto dto :dtoList) {
            double v = validBuyQuantity(loginUser.getMemberId(), loginUser.getMemberRoleId(), dto, activityGoodsRestrictNum, checkTypeEnum);
            if(v>-1&&GoodsQuantityCheckTypeEnum.CALCULATE_PRICE.equals(checkTypeEnum)){
                //如果用户端购买超限，返回超限数量给前端
                dto.setEnableQuantity(v);
                isOverrun=true;
            }
        }
        //如果用户端调用+数量超限，返回所有超限产品项
        if(GoodsQuantityCheckTypeEnum.CALCULATE_PRICE.equals(checkTypeEnum)&&isOverrun){
            return dtoList;
        }

        //拼团
        CartActivityPriceDto cartActivityPriceDto = dtoList.get(0);
        if(activityTypeSet.contains(ActivityTypeEnum.GROUP_PURCHASE.getCode())&&cartActivityPriceDto.getJoinGroup()!=null&&cartActivityPriceDto.getJoinGroup()){
            //拼团商品不能与其它商品一块下单
            if(dtoList.size()>1){
                throw new BusinessException(ResponseCode.MARKETING_ACTIVITY_GROUP_PURCHASE_GOODS_ERROR);
            }
            if(cartActivityPriceDto.getEnableActivityList().size()>1){
                log.warn("拼团商品设置错误,该商品参与了含拼团以外的活动，dto:{}",JSONUtil.toJsonStr(cartActivityPriceDto));
                throw new BusinessException(ResponseCode.MARKETING_ACTIVITY_GROUP_PURCHASE_GOODS_CONFIG_ERROR);
            }
            ActivityGoodsBO activityGoodsBO = cartActivityPriceDto.getEnableActivityList().get(0);
            /*GroupPurchaseBO groupPurchaseBO=(GroupPurchaseBO)activityGoodsBO.getActivityDefined();
            //如果用户参团限制
            if(groupPurchaseBO.getJoinAssembleStatus()==1){
                //查询参团缓存限制 TODO 产品已调整去掉
            }*/
            cartActivityPriceDto.setBasePrice(cartActivityPriceDto.getGoodsPrice());
            cartActivityPriceDto.setHandPrice(activityGoodsBO.getActivityPrice().doubleValue());
            BigDecimal salePrice = BigDecimal.valueOf(cartActivityPriceDto.getGoodsPrice()).subtract(activityGoodsBO.getActivityPrice());
            //记录参数的活动
            double saleTotalAmount = salePrice.multiply(BigDecimal.valueOf(cartActivityPriceDto.getQuantity())).doubleValue();
            recordJoinActivity(cartActivityPriceDto,activityGoodsBO,salePrice.doubleValue(),saleTotalAmount);
            cartActivityPriceDto.setSaleTotalAmount(saleTotalAmount);
            return Collections.singletonList(cartActivityPriceDto);
        }
        //3查询会员的权益系数
        List<MemberAndRoleIdDTO> upperMemberList = new ArrayList<>();
        for (CartActivityPriceDto o : dtoList) {
            MemberAndRoleIdDTO memberAndRoleIdDTO = new MemberAndRoleIdDTO(o.getUpperMemberId(), o.getUpperRoleId());
            upperMemberList.add(memberAndRoleIdDTO);
        }
        Map<String, Double> memberPriceRight = memberFeignService.getMemberPriceRight(loginUser.getMemberId(), loginUser.getMemberRoleId(), upperMemberList);
        log.info("-------3----------memberPriceRight:{}", JSONUtil.toJsonStr(memberPriceRight));

        //4获得单价叠加权益系数的价格   单价活动(特价/直降/折扣) 或 策略价 或 商品原价
        for(CartActivityPriceDto dto : dtoList){
            //排除赠品与换购的计算
            if(dto.getParentSkuId()==null) {
                calculateBasePrice(dto, memberPriceRight);
            }
        }
        log.info("-------4----------:{}", JSONUtil.toJsonStr(dtoList));

        //4.2计算叠加满减或满额的优惠价  满额存在跨店以及商品组合计算
        calculateFullCondition(dtoList);
        log.info("-------4.2----------:{}", JSONUtil.toJsonStr(dtoList));

        //5计算多件优惠价格-x
        for(CartActivityPriceDto dto : dtoList){
            //排除赠品与换购的计算
            if(dto.getParentSkuId()==null) {
                calculateMorePiece(dto);
            }
        }
        log.info("-------5----------:{}", JSONUtil.toJsonStr(dtoList));

        //6计算组合优惠价格-g
        calculateCombination(dtoList);
        log.info("-------6----------:{}", JSONUtil.toJsonStr(dtoList));

        //7计算换购商品价格-g
        if(swapActivityMap.size()>0){
            calculateSwap(dtoList,swapActivityMap);
        }
        log.info("-------7----------:{}", JSONUtil.toJsonStr(dtoList));

        //8加载赠送促销信息-x
        loadGiftList(dtoList);
        log.info("-------8----------:{}", JSONUtil.toJsonStr(dtoList));

        //9套餐活动-x
        loadSetMealList(dtoList);
        log.info("-------9----------:{}", JSONUtil.toJsonStr(dtoList));

        //10秒杀(不在秒杀时间段内，恢复原价购买)-x
        if(activityTypeSet.contains(ActivityTypeEnum.SEC_KILL.getCode())){
            for(CartActivityPriceDto dto : dtoList){
                //排除赠品与换购的计算
                if(dto.getParentSkuId()==null) {
                    calculateSecKill(dto);
                }
            }
        }
        log.info("-------10----------:{}", JSONUtil.toJsonStr(dtoList));
        //10返回参数
        for(CartActivityPriceDto dto :dtoList){
            //合计sku总优惠
            List<SkuJoinActivityResponse> activityList = dto.getActivityList();
            if(CollectionUtil.isNotEmpty(activityList)){
                Double saleTotalAmount = activityList.stream().map(SkuJoinActivityResponse::getSaleTotalAmount).filter(Objects::nonNull).reduce(0D, NumberUtil::add);
                dto.setSaleTotalAmount(saleTotalAmount);
            }
            //过滤负数
            if(dto.getHandPrice()!=null&&dto.getHandPrice()<0){
                dto.setHandPrice(0D);
            }
        }

        return dtoList;
    }

    private CartActivityPriceResponse bulidCartActivityPriceResponse(CartActivityPriceDto dto){
        CartActivityPriceResponse response=new CartActivityPriceResponse();
        response.setBasePrice(dto.getBasePrice());
        response.setGoodsPrice(dto.getGoodsPrice());
        response.setHandPrice(dto.getHandPrice());
        response.setGroupHandPrice(dto.getGroupHandPrice());
        response.setGroupNo(dto.getGroupNo());
        response.setGiveList(dto.getGiveList());
        response.setCommodityType(dto.getCommodityType());
        response.setParentSkuId(dto.getParentSkuId());
        response.setProductId(dto.getProductId());
        response.setQuantity(dto.getQuantity());
        response.setSkuId(dto.getSkuId());
        response.setShopId(dto.getShopId());
        response.setParameter(dto.getParameter());
        response.setSaleTotalAmount(dto.getSaleTotalAmount());
        response.setEnableQuantity(dto.getEnableQuantity());
        response.setPurchaseId(dto.getPurchaseId());
        return response;
    }

    private CartActivityPriceFeignResponse bulidCartActivityPriceFeignResponse(CartActivityPriceDto dto){
        CartActivityPriceFeignResponse response=new CartActivityPriceFeignResponse();
        response.setBasePrice(dto.getBasePrice());
        response.setGoodsPrice(dto.getGoodsPrice());
        response.setHandPrice(dto.getHandPrice());
        response.setGroupHandPrice(dto.getGroupHandPrice());
        response.setGroupNo(dto.getGroupNo());
        response.setGiveList(dto.getGiveList());
        response.setCommodityType(dto.getCommodityType());
        response.setParentSkuId(dto.getParentSkuId());
        response.setProductId(dto.getProductId());
        response.setQuantity(dto.getQuantity());
        response.setSkuId(dto.getSkuId());
        response.setShopId(dto.getShopId());
        response.setActivityList(dto.getActivityList());
        response.setParameter(dto.getParameter());
        response.setSaleTotalAmount(dto.getSaleTotalAmount());
        return response;
    }

    private CartSubsidiaryResponse buildCartSubsidiaryResponse(SubsidiaryDto o){
        CartSubsidiaryResponse subResponse = new CartSubsidiaryResponse();
        subResponse.setId(o.getId());
        subResponse.setName(o.getName());
        subResponse.setBrand(o.getBrand());
        subResponse.setCategory(o.getCategory());
        subResponse.setUnit(o.getUnit());
        subResponse.setGroupNo(o.getGroupNo());
        subResponse.setGroupPrice(o.getGroupPrice());
        subResponse.setPrice(o.getPrice());
        subResponse.setHandPrice(o.getHandPrice());
        subResponse.setNum(o.getNum());
        subResponse.setLimitValue(o.getLimitValue());
        subResponse.setProductId(o.getProductId());
        subResponse.setProductImgUrl(o.getProductImgUrl());
        return subResponse;
    }


    @Override
    public Wrapper<List<CartActivityPriceResponse>> calculateActivityPrice(UserLoginCacheDTO loginUser, List<CartActivityPriceRequest> req) {
        List<CartActivityPriceDto> data = calculateActivityPriceFinal(loginUser, req,GoodsQuantityCheckTypeEnum.CALCULATE_PRICE);
        List<CartActivityPriceResponse> baseResponseList=new ArrayList<>();
        for(CartActivityPriceDto dto :data){
            CartActivityPriceResponse response=bulidCartActivityPriceResponse(dto);
            baseResponseList.add(response);
            if(CollectionUtil.isNotEmpty(dto.getSetMealList())){
                List<CartSubsidiaryResponse> setMealList = dto.getSetMealList().stream().map(this::buildCartSubsidiaryResponse).collect(Collectors.toList());
                response.setSetMealList(setMealList);
            }
        }
        return Wrapper.success(baseResponseList);
    }

    @Override
    public Wrapper<List<CartActivityPriceFeignResponse>> calculateActivityPriceByFeign(UserLoginCacheDTO loginUser, List<CartActivityPriceRequest> req) {
        List<CartActivityPriceDto> data = calculateActivityPriceFinal(loginUser, req,GoodsQuantityCheckTypeEnum.CALCULATE_PRICE_FEIGN);
        List<CartActivityPriceFeignResponse> baseResponseList=new ArrayList<>();
        for(CartActivityPriceDto dto :data){
            CartActivityPriceFeignResponse response=bulidCartActivityPriceFeignResponse(dto);
            baseResponseList.add(response);
            if(CollectionUtil.isNotEmpty(dto.getSetMealList())){
                List<CartSubsidiaryResponse> setMealList = dto.getSetMealList().stream().map(this::buildCartSubsidiaryResponse).collect(Collectors.toList());
                response.setSetMealList(setMealList);
            }
        }
        return Wrapper.success(baseResponseList);
    }

    @Override
    public Wrapper<Double> checkQuantityByAddCart(UserLoginCacheDTO loginUser, ActivityGoodsQuantityCheckRequest request) {
        //入参转dto
        CartActivityPriceDto dto = new CartActivityPriceDto();
        BeanUtils.copyProperties(request, dto);
        //查询skuId参与的活动
        List<ActivityGoodsBO> skuAllActivityList = activityPriceCalculateComponent.getSkuAllActivityList(dto.getShopId(), dto.getSkuId(), new MemberAndRoleIdBO(loginUser.getMemberId(), loginUser.getMemberRoleId()));
        if(CollectionUtil.isEmpty(skuAllActivityList)){
            return Wrapper.success();
        }
        dto.setEnableActivityList(skuAllActivityList);
        //查询活动商品的限购数量
        List<Long> activities = skuAllActivityList.stream().map(ActivityGoodsBO::getActivityId).collect(Collectors.toList());
        Map<String, ActivityGoodsRestrictNumResp> activityGoodsRestrictNum = activityGoodsCacheService.getActivityGoodsRestrictNum(activities, Collections.singletonList(dto.getSkuId()));
        //如果为加入进货单操作(则累加购物车中已添加的数量)
        if(GoodsQuantityCheckTypeEnum.ADD_TO_CART.getCode().equals(request.getOperateType())){
            Wrapper<Double> purchaseCommodityCount = searchFeignService.getPurchaseCommodityCount(dto.getShopId(), loginUser.getMemberId(), loginUser.getMemberRoleId(), dto.getSkuId());
            if(purchaseCommodityCount.getCode()==Wrapper.success().getCode()){
                dto.setQuantity(NumberUtil.add(dto.getQuantity(),purchaseCommodityCount.getData()));
                dto.setCartQuantity(purchaseCommodityCount.getData());
            }
        }
        //校验数量
        Double enableNum=validBuyQuantity(loginUser.getMemberId(),loginUser.getMemberRoleId(),dto,activityGoodsRestrictNum,GoodsQuantityCheckTypeEnum.find(request.getOperateType()));
        return Wrapper.success(enableNum);
    }
}
